package com.bkitmobile.kesu.android.GUI;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.DialogInterface.OnClickListener;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.appenginefan.toolkit.common.ClientSocketSubstitute;
import com.bkitmobile.kesu.android.ClassInfo.FriendShortInfo;
import com.bkitmobile.kesu.android.ClassInfo.FriendsListAdapter;
import com.bkitmobile.kesu.android.ClassInfo.StoreMessage;
import com.bkitmobile.kesu.android.ClassInfo.UserConfig;
import com.bkitmobile.kesu.android.connectServer.Request;
import com.bkitmobile.kesu.android.connectServer.ServiceCallback;
import com.bkitmobile.kesu.android.connectServer.staticClass;
import com.bkitmobile.kesu.android.service.ServiceLocationConnection;
import com.bkitmobile.kesu.android.service.UpdateLocationService;
public class FriendsList extends ListActivity{
	public static final boolean ONLINE = true;
	public static final boolean OFFLINE = false;
	public static final boolean INVISIBLE = false;
	public static final int HANDLER_MSG_WAIT = 1;
	public static Message msg;
	private boolean state;
	private FriendsListAdapter listAdapter; //use for list
	private List<String> friendsName;
	private EditText txtFind;
	private TextView txtFindBehide, titlebar;
	private List<FriendShortInfo> friendsList, friendsListTemplate;
	private Dialog dialogAddFriend = null, dialogFindLocation = null, dialogChangeStatus = null, sendMessDlg = null;
	private HashMap<String,FriendShortInfo> friendsListHash = null;
	private boolean viewOffline = true;
	private ServiceConnection mConnection;
	private UpdateLocationService service;
	private Bundle extras;
	private String userLogin;
	private String currentMessage;
	private Handler exitHandler;
	private boolean isNear;
	private boolean isFavorite;
	private Handler handler = new Handler();
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		Intent intent = new Intent(this, UpdateLocationService.class);
		startService(intent);
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.friend__friends_list);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
		titlebar = (TextView) findViewById(R.id.custom_title);
		// Define a set of criteria used to select a location provider.

	    extras = getIntent().getExtras();
	    try {
	    	state = extras.getBoolean("state");
	    } catch (Exception e)
	    {
	    	
	    }
	    Log.d("state", state+"");
		friendsListHash = new HashMap<String, FriendShortInfo>();
		staticClass.isActivity = true;
    	staticClass.socket.println("<login>" + staticClass.user);
    	staticClass.isActived = new LinkedList<String>();
		try{
			userLogin = extras.getString("username");
			staticClass.user = userLogin;
			
		} catch (Exception e)
		{
			userLogin = staticClass.user;
		}
		if (!staticClass.isRunning)
		{
			String value = extras.getString("list");
			currentMessage = value;
			List<FriendShortInfo> list;
			list = receive(value);	
			init(list);
		}
		staticClass.mHandler = new Handler(){
			@Override
    		public void handleMessage(Message msg){
				if (msg.what == 100){
					if (service == null){
						service = ((ServiceLocationConnection)mConnection).getService();
						if (msg.getData().hasFileDescriptors()) return;
					}
					String update = msg.getData().getString("string");
					if (update!=null){
						Log.d("error gi day", update);
						if (update.startsWith("<chat>")){
							String id = update.substring(
									update.indexOf("<from>")+6,
									update.lastIndexOf("<message>"));
							//Toast.makeText(FriendsList.this, 
							//		"You've got a message from "+id, Toast.LENGTH_LONG)
							//					.show();
						}
						else if (update.startsWith("<flogin>")){
								//to do update list
							String user = update.substring(
									update.indexOf("<flogin>")+8,
									update.indexOf("<status>")
									);
							FriendShortInfo fr = friendsListHash.get(user);
							fr.setState(true);
							fr.setStatus(update.substring(
									update.indexOf("<status>")+8
									));
							listAdapter.notifyDataSetChanged();
						} else if (update.startsWith("<flogout>"))
						{
							//to do update list
							String user = update.substring(
									update.indexOf("<flogout>")+9
									);
							FriendShortInfo fr = friendsListHash.get(user);
							fr.setState(false);
							listAdapter.notifyDataSetChanged();
						} else if (update.startsWith("<fstatus>")){
							String user = update.substring(
									update.indexOf("<fstatus>")+9,
									update.lastIndexOf("<status>")
									);
							String status = update.substring(
									update.lastIndexOf("<status>")+8
									);
							
							FriendShortInfo fr = friendsListHash.get(user);
							fr.setStatus(status);
							listAdapter.notifyDataSetChanged();
						}
						else if (update.startsWith("<add>"))
						{
							//to do show message add friend
							AcceptInviteDlg dialog = new AcceptInviteDlg(FriendsList.this
									, update.substring(update.indexOf("<add>")+5
											, update.indexOf("<cmt>"))
									,  update.substring(update.indexOf("<cmt>")+5)
									);
							dialog.show();
						} else if (update.startsWith("<accept>"))
						{
							//to do insert to list
							String user = update.substring(
									update.indexOf("<accept>")+8,
									update.indexOf("<status>")
									);
							FriendShortInfo fr = friendsListHash.get(user);
							fr.setState(true);
							fr.setStatus(update.substring(
									update.indexOf("<status>")+8,
									update.lastIndexOf("<state>")
									));
							fr.setState(update.substring(
									update.lastIndexOf("<state>")+7
									).startsWith("onl")
									);			
							listAdapter.notifyDataSetChanged();								
						} else if (update.startsWith("<fadd>"))
						{
							//to do insert to list
							String user = update.substring(
									update.indexOf("<fadd>")+6,
									update.indexOf("<status>")
									);
							String status = update.substring(
									update.indexOf("<status>")+8,
									update.lastIndexOf("<state>")
									);
							boolean state = update.substring(
									update.lastIndexOf("<state>")+7,
									update.lastIndexOf("<img>")
									).startsWith("onl");
							String img = update.substring(
									update.lastIndexOf("<img>")+5
										);
							FriendShortInfo fr = new FriendShortInfo(user, status, state,img);
							addFriend(fr);
						} else if (update.startsWith("<deny>"))
						{
							//to do remove from list
							String user = update.substring(
									update.indexOf("<deny>")+6);
							FriendShortInfo fr = friendsListHash.get(user);
							listAdapter.remove(fr);
							friendsListHash.remove(user);
							friendsName.remove(user);
							listAdapter.notifyDataSetChanged();
						} else if (update.startsWith("<remove>"))
						{
							//to do remove from list
							String user = update.substring(
									update.indexOf("<remove>")+8);
							FriendShortInfo fr = friendsListHash.get(user);
							listAdapter.remove(fr);
							friendsListHash.remove(user);
							friendsName.remove(user);
							listAdapter.notifyDataSetChanged();
						} else if (update.startsWith("<AnotherLogin>"))
						{
							StaticDialogs.okButtonDialog(FriendsList.this,"You've been sign out " +
									"because you sign in on a different device");
							Bundle data = new Bundle();
							data.putBoolean("isExit", false);
							Message message = new  Message();
							message.setData(data);
							exitHandler.sendMessageDelayed(message, 5000);
						} else if (update.startsWith("<AddSuccess>"))
						{
							 addFriend(new FriendShortInfo(update.substring(12),"waiting confirm invite",false,null));
							 
						} else if (update.startsWith("<AddNotExist>"))
						{
							StaticDialogs.okButtonDialog(FriendsList.this, 
									Html.fromHtml("User: <b><font color=\"#3399ff\">"
											+update.substring(13)+" </font></b>does not exist<br/>"));
						}else if (update.startsWith("<msg>"))
                        {
                            String uFrom = null;
                            String mess = null;
                            uFrom = update.substring(
                                            update.lastIndexOf("<uFrom>")+7
                                            );
                             mess = update.substring(5,
                                            update.lastIndexOf("<uFrom>")
                                            );
                            StaticDialogs.okButtonDialog(FriendsList.this, 
                                            Html.fromHtml("User: <b><font color=\"#3399ff\">"
                                                            +uFrom+" </font></b>has sent you a message:\n"+mess+"<br/>"));
                        } else if (update.startsWith("<AllowFollowMe>"))
                        {
                        	String name = update.substring(
                        			update.indexOf("<u>")+3
                        			).trim();
                        	if(update.substring(15).startsWith("succ")){
            					friendsListHash.get(name).setCanViewInvi(true);
            				}
            				else{
            					friendsListHash.get(name).setCanViewInvi(false);
            					StaticDialogs.okButtonDialog(FriendsList.this, "Allow Follow", "Have an error");
            				}
                        } else if (update.startsWith("<DisallowFollowMe>"))
                        {
                        	String name = update.substring(
                        			update.indexOf("<u>")+3
                        			).trim();
                        	if(update.substring(18).startsWith("succ")){
                        		friendsListHash.get(name).setCanViewInvi(false);
            				}
            				else{
            					friendsListHash.get(name).setCanViewInvi(true);
            					StaticDialogs.okButtonDialog(FriendsList.this, "Disallow Follow", "Have an error");
            				}
                        } else if (update.startsWith("<AllowSee24>"))
                        {
                        	String name = update.substring(
                        			update.indexOf("<u>")+3
                        			).trim();
                        	if(update.substring(12).startsWith("succ")){
                        		friendsListHash.get(name).setCanSee24h(true);
            				}else{
            					friendsListHash.get(name).setCanSee24h(false);
            					StaticDialogs.okButtonDialog(FriendsList.this, "Allow friend see 24h", "Have an error in process");
            				}
                        } else if (update.startsWith("<DisallowSee24>"))
                        {
                        	String name = update.substring(
                        			update.indexOf("<u>")+3
                        			).trim();
                        	if(update.substring(15).startsWith("succ")){
                        		friendsListHash.get(name).setCanSee24h(false);
            				}
            				else{
            					friendsListHash.get(name).setCanSee24h(true);
            					StaticDialogs.okButtonDialog(FriendsList.this, "Disallow see 24h", "Have an error in process");
            				}
                        }
						else {
							//System.out.println(update.startsWith("<fadd>"));
							List<FriendShortInfo> list1 = receive(update);	
							if (list1!=null) init(list1);
						}
					} else 
					{
						
					}
				}
			}
		};	
		
		mConnection = new ServiceLocationConnection();
		bindService(new Intent(getApplicationContext(), 
				UpdateLocationService.class), mConnection, BIND_AUTO_CREATE);
		exitHandler = new Handler(){
			public void handleMessage(Message msg){
				super.handleMessage(msg);
				boolean isExit = msg.getData().getBoolean("isExit");
				if (isExit){
					stopService(new Intent(FriendsList.this,UpdateLocationService.class));
					unbindService(mConnection);
					finish();
			    	System.exit(1);
				} else {
					
			    	unbindService(mConnection);
			    	staticClass.socket.close();
			    	stopService(new Intent(FriendsList.this,UpdateLocationService.class));	
			    	startActivity(new Intent(FriendsList.this, Login.class));
			    	staticClass.rebuild();
			    	finish();
				}
			}
		};
		titlebar.setText(userLogin + " | Friends list - KeSu");
	}
	public void onListItemClick(ListView parent, View v, final int position, long id) {
		final FriendShortInfo user = listAdapter.getItem(position);
		final String userId = user.getId();
		final String []str = new String[8];
		str[0] = getString(R.string.friend_menu_chat);
		str[1] = getString(R.string.friend_menu_profile);
		str[2] = getString(R.string.friend_menu_view)
				+" ["+ userId + "]" + getString(R.string.friend_menu_location);
		str[3] = getString(R.string.friend_menu_view) 
				+" ["+ userId + "]" + getString(R.string.friend_menu_24h);
		str[4] = (user.isCanViewInvi()? getString(R.string.friend_menu_deny)
									: getString(R.string.friend_menu_allow))
				+" ["+ userId +"] "+ getString(R.string.friend_menu_follow);
		str[5] = (user.isCanSee24h()? getString(R.string.friend_menu_deny)
				: getString(R.string.friend_menu_allow))
				+" ["+ userId +"] "+ getString(R.string.friend_menu_see24h);
		str[6] = getString(R.string.friend_menu_remove);
		//TODO: get infomation to build menulist
		final CharSequence []menuForOnline = {str[0], str[1], str[2], str[3], str[4], str[5], str[6]};
		final CharSequence []menuForOffline ={str[0], str[1], str[3], str[4], str[5], str[6]};
		final CharSequence []menuForWaiting = {str[0], str[4], str[6]};
		
		final CharSequence []menuList = (user.isState() ? menuForOnline :
								(user.isWaitingAdd() ? menuForWaiting:menuForOffline));
		Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(user.getId());
		builder.setItems(menuList, new OnClickListener() {
			
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				
				int index = solveMenu(which);
				Log.d("Item Click", str[index]);
				switch(index){
					case 0: //chat
						Intent intent = new Intent(FriendsList.this, ChatActivity.class);
						intent.putExtra("chatter", userId);
						startChat(intent); 
						break;
					case 1: //profile
						StaticDialogs.profileDialog(FriendsList.this, friendsList.get(position).getId());
						
						break;
					case 2: //view location

						try {
							Intent toMapIntent = new Intent(FriendsList.this, KesuMap.class);
							toMapIntent.putExtra("manage",false);
							toMapIntent.putExtra("longitude", UpdateLocationService.currentLocation.getLongitude());
							toMapIntent.putExtra("latitude", UpdateLocationService.currentLocation.getLatitude());
							getLocations(UpdateLocationService.currentLocation.getLatitude(),UpdateLocationService.currentLocation.getLongitude(),toMapIntent,false,user);
							toMapIntent.putExtra("focus", false);
						} catch (NullPointerException e)
						{
							StaticDialogs.okButtonDialog(FriendsList.this, getString(R.string.gps_not_available));
						}
						break;
					case 3: //view 24h
						String []identities = {"ID", "person"};
						String []atributies = {Request.GETLISTPOSITION, friendsList.get(position).getId()};
						Request.sendAndRecieveData(identities, atributies, true,FriendsList.this,new ServiceCallback<String>() {
							
							@Override
							public void onSuccess(final String result) {
								// TODO Auto-generated method stub
								handler.post(new Runnable() {
									
									@Override
									public void run() {
										// TODO Auto-generated method stub
										Log.d("locations", result);
										JSONObject obj = null;
										String data = null;
										try {
											obj = new JSONObject(result);
											String mess = obj.getString("result");
											if (!mess.startsWith("succ")){
												StaticDialogs.okButtonDialog(FriendsList.this, mess);
												return;
											}
											else data = obj.getString("listLocation");
										} catch (JSONException e1) {
											// TODO Auto-generated catch block
											e1.printStackTrace();
										}
										
										Intent mapIntent = new Intent(FriendsList.this, KesuMap.class);
										mapIntent.putExtra("manage",true);
										mapIntent.putExtra("data",data);
										startActivity(mapIntent);
									}
								});
							}
							
							@Override
							public void onFailure(Exception exception) {
								// TODO Auto-generated method stub
								handler.post(new Runnable() {
									
									@Override
									public void run() {
										// TODO Auto-generated method stub
										StaticDialogs.okButtonDialog(FriendsList.this
												, FriendsList.this.getString(R.string.disconnect));
									}
								});
								
							}
						});
						
						break;
					
					case 4: //allow follow me
						if(user.isCanViewInvi()){
							disallowPersonFollowMe(position);
						}else{
							allowPersonFollowMe(position);
						}
						break;
					case 5: //allow see 24h
						if(user.isCanSee24h()){
							disallowPersonSee24(position);
						}else{
							final Dialog dg = new Dialog(FriendsList.this);
							dg.requestWindowFeature(Window.FEATURE_NO_TITLE);
							dg.setContentView(R.layout.reinput_password);
							final Button btnOk;
							Button btnCancel;
							final EditText txtPass;
							btnOk = (Button) dg.findViewById(R.id.reinput_pass_ok);
							btnCancel = (Button) dg.findViewById(R.id.reinput_pass_cancel);
							txtPass = (EditText) dg.findViewById(R.id.reinput_pass);
							android.view.View.OnClickListener click = new View.OnClickListener() {
								
								@Override
								public void onClick(View v) {
									if(v == btnOk){
										String pass = txtPass.getText().toString();
										if(pass.equals(Login.getPass())){
											dg.dismiss();
											allowPersonSee24(position);
										}
										else{
											dg.dismiss();
											StaticDialogs.okButtonDialog(FriendsList.this, "Error", "Incorrect password!");
										}
											
									}
									if(dg.isShowing())
										dg.dismiss();
								}
							};
							btnOk.setOnClickListener(click);
							btnCancel.setOnClickListener(click);
							dg.show();
						}
						
						break;
					case 6: //remove
						try {
							removeFriend(position);
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						break;
					case 7://send message/
						/*
						if(sendMessDlg == null)
							sendMessDlg = new SendMessageDlg(FriendsList.this);
						((SendMessageDlg)sendMessDlg).show(userId);
						break;*/
					
				}
				
			}
			int solveMenu(int index){
				int result = index;
				
				if(menuList == menuForOffline){
					switch(index){
						case 0:
						case 1:
							break;
						default:
							result +=1;
					}
				}else if (menuList == menuForWaiting){
					switch(index){
						case 0:
							result = 0;
							break;
						case 1:
							result = 4;
							break;
						case 2:
							result = 6;
							break;
					}
				}
				
				return result;
			}
			
		});
		
		AlertDialog menu = builder.create();
		menu.show();
	}
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK)
		{
			unbindService(mConnection);
			staticClass.isActivity = false;
			staticClass.isFirst = false;
			//staticClass.socket.close();
			finish();
			return true;
		}
		
		return(super.onKeyDown(keyCode, event));
	}
	public boolean onCreateOptionsMenu(Menu menu) {
		new MenuInflater(getApplication()).inflate(R.menu.menu, menu);
		boolean result = super.onCreateOptionsMenu(menu);
		if(state == INVISIBLE)
			menu.findItem(R.id.menu_state_online).setTitle(R.string.menu_state_online);
		else
			menu.findItem(R.id.menu_state_online).setTitle(R.string.menu_state_invisible);
		return (result);
	}
	
	
	
	
	public boolean onOptionsItemSelected(MenuItem item) {
		//System.out.println(item.);
		 
		switch(item.getItemId()){
			//--------------basic
			case R.id.menu_exit:
				doExit();
				
				break;
				
			case R.id.menu_logout:
				doLogOut();	
				break;
				
			case R.id.menu_setting:
					Intent setting = new Intent(this, Setting.class);
					setting.putExtra("config", service.getuConfig());
					startActivity(setting);
				
				break;
				
			//------------------- friends list
			case R.id.menu_friendsList_view:
				System.out.println("press menu_friendsList_view");
				txtFind.setText(null);
				txtFindBehide.setText(getString(R.string.friend_findBehide));
				restoreFriendList();
				listAdapter.notifyDataSetChanged();
				
				break;
			case R.id.menu_friendsList_addFriend:
				System.out.println("press add friend");
				if(dialogAddFriend == null){
					dialogAddFriend = new AddFriendDialog(this);
				}
				dialogAddFriend.show();
				break;
				
			case R.id.menu_friendsList_onlineOnly:
				System.out.println("press online Only");
				onlineOnly();
				break;
				
			case R.id.menu_friendsList_seen24:
				System.out.println("press menu_friendsList_seen24");
				seeWhoCanSee24h();
				break;
				
			case R.id.menu_friendsList_seenInvisible:
				System.out.println("press menu_friendsList_seenInvisible");
				//TODO: more seen invisible
				seeSetAvailableList();
				
				break;
				
			//------------------- chat
			case R.id.menu_chat:
				if(ChatActivity.isStated){
					Intent intent = new Intent(FriendsList.this, ChatActivity.class);
					startChat(intent);
				}
				else{
					StaticDialogs.okButtonDialog(FriendsList.this, "No chatter in chat");
				}
				break;
			  
			//------------------- location
			case R.id.menu_location_findLocation:
				Intent intentSearch = new Intent(FriendsList.this,PlaceList.class);
				intentSearch.putExtra("lng", UpdateLocationService.currentLocation.getLongitude());
				intentSearch.putExtra("lat", UpdateLocationService.currentLocation.getLatitude());
				intentSearch.putExtra("search", true);
				startActivity(intentSearch);
				break;
			
			case R.id.menu_location_myLocation:
				System.out.println("press menu_myLocation");
				try {
					Intent toMapIntent = new Intent(FriendsList.this, KesuMap.class);
					toMapIntent.putExtra("manage",false);
					toMapIntent.putExtra("longitude", UpdateLocationService.currentLocation.getLongitude());
					toMapIntent.putExtra("latitude", UpdateLocationService.currentLocation.getLatitude());
					toMapIntent.putExtra("focus", true);
				//Log.e("lat", msg.getData().getDouble("longtitude")+"");
					getLocations(UpdateLocationService.currentLocation.getLatitude(),UpdateLocationService.currentLocation.getLongitude(),toMapIntent,true,null);
				} catch (NullPointerException e)
				{
					StaticDialogs.okButtonDialog(this, getString(R.string.gps_not_available));
				}
				break;
			//------------------- state
			case R.id.menu_state_online:
				System.out.println("press menu_state_online:"+state);
				if(state == INVISIBLE)
				{
					item.setTitle(R.string.menu_state_invisible);
					state = ONLINE;
					String req = "<state>available";
					Log.d("request", req);
					staticClass.socket.println(req);
				}
				else
				{
					item.setTitle(R.string.menu_state_online);
					state = INVISIBLE;
					String req = "<state>invisible";
					Log.d("request", req);
					staticClass.socket.println(req);
				}
				break;
			case R.id.menu_state_status:
				System.out.println("press menu_state_state");
				/*setStatus();*/
				if(dialogChangeStatus == null){

					dialogChangeStatus = new SetStatus(this,UpdateLocationService.currentLocation.getLongitude(),UpdateLocationService.currentLocation.getLatitude());
				}
				dialogChangeStatus.show();
				break;
			//TODO something
		}
		return(super.onOptionsItemSelected(item));
	}
	public ListAdapter getListAdapter()
	{
		return listAdapter;
	}
	private Intent toMapIntent;
	private void getLocations(double lat,double lng,Intent toMapIntent, final boolean isMyLocation,final FriendShortInfo user)
	{
		String []identities = {"ID","lat","lng"};
		String []atributies = {Request.GET_LOCATIONS,String.valueOf(lat),String.valueOf(lng)};
		FriendsList.this.toMapIntent = toMapIntent;
		Request.sendAndRecieveData(identities, atributies, true,this,new ServiceCallback<String>() {
			
			@Override
			public void onSuccess(final String result) {
				// TODO Auto-generated method stub
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						
						String listPlace = null;
						try{
							JSONObject obj = new JSONObject(result);
							JSONArray lsUpdate = new JSONArray(obj.getString("fLocation"));
							for (int i = 0 ; i < lsUpdate.length() ; i++)
							{
								JSONObject object = lsUpdate.getJSONObject(i);
								FriendShortInfo fr = friendsListHash.get(object.getString("user"));
								fr.setLatitude(object.getDouble("lat"));
								fr.setLongitude(object.getDouble("long"));
								fr.setTime(object.getString("time"));
								fr.setsLatitude(object.getDouble("slat"));
								fr.setsLongitude(object.getDouble("slong"));
								fr.setsTime(object.getString("stime"));
							}
							isNear = obj.getBoolean("isNear");
							isFavorite = obj.getBoolean("isFavorite");
							listPlace =  obj.getString("pLocation");
						} catch (JSONException e)
						{
							listPlace = null;
						}
						if (!isMyLocation)
						{
							FriendsList.this.toMapIntent.putExtra("isNear", isNear);
							FriendsList.this.toMapIntent.putExtra("isFavorite", isFavorite);
							if (listPlace == null) FriendsList.this.toMapIntent.putExtra("psize",0);
							else {
								try{
									JSONArray js = new JSONArray(listPlace);
									FriendsList.this.toMapIntent.putExtra("psize",js.length());
									for (int i = 0 ; i < js.length() ; i++)
									{
										JSONObject obj = js.getJSONObject(i);
										FriendsList.this.toMapIntent.putExtra("p"+i+"lat", obj.getDouble("lat"));
										FriendsList.this.toMapIntent.putExtra("p"+i+"lng", obj.getDouble("lng"));
										FriendsList.this.toMapIntent.putExtra("p"+i+"name", obj.getString("name"));
										FriendsList.this.toMapIntent.putExtra("p"+i+"type", obj.getString("type"));
										try {
											if (isNear && isFavorite)
												FriendsList.this.toMapIntent.putExtra("p"+i+"load", obj.getInt("load"));
											} catch (JSONException e){
												e.printStackTrace();
												continue;
											}	
									}
								} catch (JSONException e)
								{
									e.printStackTrace();
								}
							}
							
							FriendsList.this.toMapIntent.putExtra("flongitude", user.getLongitude());
							FriendsList.this.toMapIntent.putExtra("flatitude", user.getLatitude());
							//Log.e("lat", msg.getData().getDouble("longtitude")+"");
							FriendsList.this.toMapIntent.putExtra("size", friendsList.size());
							for (int i = 0 ; i < friendsList.size() ; i++)
							{
								FriendsList.this.toMapIntent.putExtra("friend"+i, friendsList.get(i));
							}
							startActivity(FriendsList.this.toMapIntent);	
						} else {
							FriendsList.this.toMapIntent.putExtra("isNear", isNear);
							FriendsList.this.toMapIntent.putExtra("isFavorite", isFavorite);
							if (listPlace == null) FriendsList.this.toMapIntent.putExtra("psize",0);
							else {
								try{
									JSONArray js = new JSONArray(listPlace);
									FriendsList.this.toMapIntent.putExtra("psize", js.length());
									for (int i = 0 ; i < js.length() ; i++)
									{
										JSONObject obj = js.getJSONObject(i);
										FriendsList.this.toMapIntent.putExtra("p"+i+"lat", obj.getDouble("lat"));
										FriendsList.this.toMapIntent.putExtra("p"+i+"lng", obj.getDouble("lng"));
										FriendsList.this.toMapIntent.putExtra("p"+i+"name", obj.getString("name"));
										FriendsList.this.toMapIntent.putExtra("p"+i+"type", obj.getString("type"));
										try {
										if (isNear && isFavorite)
											FriendsList.this.toMapIntent.putExtra("p"+i+"load", obj.getInt("load"));
										} catch (JSONException e){
											e.printStackTrace();
											continue;
										}
									}
								} catch (JSONException e)
								{
									e.printStackTrace();
								}
							}
							FriendsList.this.toMapIntent.putExtra("size", friendsList.size());
							for (int i = 0 ; i < friendsList.size() ; i++)
							{
								if (friendsList.get(i).isState()) FriendsList.this.toMapIntent.putExtra("friend"+i, friendsList.get(i));
							}
							startActivity(FriendsList.this.toMapIntent);	
						}
					}
				});
			}
			
			@Override
			public void onFailure(Exception exception) {
				// TODO Auto-generated method stub
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						StaticDialogs.okButtonDialog(FriendsList.this
								, FriendsList.this.getString(R.string.disconnect));
					}
				});
			}
		});
		
	}
	private void allowPersonFollowMe(final int position){

		String request = "<"+Request.ALLOW_FOLLOW_ME+">"+friendsList.get(position).getId();
		staticClass.socket.println(request);
	}
	
	private void disallowPersonFollowMe(final int position){

		String request = "<"+Request.DISALLOW_FOLLOW_ME+">"+friendsList.get(position).getId();
		staticClass.socket.println(request);
	}
	
	private void allowPersonSee24(final int position){
		String request = "<"+Request.ALLOW_SEE24+">"+friendsList.get(position).getId();
		staticClass.socket.println(request);
	}
	
	private void disallowPersonSee24(final int position){
		String request = "<"+Request.DISALLOW_SEE24+">"+friendsList.get(position).getId();
		staticClass.socket.println(request);
		
	}
	
	
	private void seeSetAvailableList() {
		for (int i = 0; i < friendsList.size(); i++){
			FriendShortInfo fr = friendsList.get(i);
			if(!fr.isCanViewInvi()){
				hideFriend(i--);
			}
		}
	}

	private void seeWhoCanSee24h() {
		for (int i = 0; i < friendsList.size(); i++){
			FriendShortInfo fr = friendsList.get(i);
			if(!fr.isCanSee24h()){
				hideFriend(i--);
			}
		}
	}

	private String doLogOut()
	{
		String msg = "<logout>"+userLogin;
		Log.d("log out", msg);
		staticClass.socket.println(msg);
		Bundle data = new Bundle();
		data.putBoolean("isExit", false);
		Message message = new  Message();
		message.setData(data);
		exitHandler.sendMessageDelayed(message, 2500);
		return "You already logged out";
	}
	private void doExit()
	{
		staticClass.isRunning = false;
		String msg = "<exit>"+userLogin;
		staticClass.socket.println(msg);
		Bundle data = new Bundle();
		data.putBoolean("isExit", true);
		Message message = new  Message();
		message.setData(data);
		exitHandler.sendMessageDelayed(message, 2500);
	}
	public void addFriend(FriendShortInfo newFriend){
		if(viewOffline == false){
			addToList(newFriend, friendsListTemplate);
		}
		else{
			int pos = findPosToInsert(newFriend, friendsList);
			listAdapter.insert(newFriend, pos);
		}
		newFriend.setWaitingAdd(true);
		friendsName.add(newFriend.getId());
		friendsListHash.put(newFriend.getId(), newFriend);
		//friendDb.UpdateOneUser(newFriend);
	}
	public boolean checkBeforeAddFriend(String newFriendId) {
		int friendListSize = friendsName.size();
		for(int i = 0; i<friendListSize; i++)
			if(newFriendId.equals(friendsName.get(i)))
				return false;
		return true;
	}
	
	private void onlineOnly(){
		//restoreFriendList();
		for (int i = 0; i < friendsList.size(); i++){
			if(friendsList.get(i).isState() == OFFLINE)
				hideFriend(i--);
		}
	}
	
	private void restoreFriendList() {
		while(friendsListTemplate.size()>0){
			FriendShortInfo fr = friendsListTemplate.get(0);
			addToList(fr, friendsList);
			friendsListTemplate.remove(0);
		}
	}
	
	private void hideFriend(int pos){
		FriendShortInfo fr = listAdapter.getItem(pos);
		listAdapter.remove(fr);
		addToList(fr, friendsListTemplate);
	}
	private boolean showFriend(String id){
		boolean result = false;
		FriendShortInfo fr = null;
		int size = friendsListTemplate.size();
		for(int i = 0; i<size; i++){
			fr = friendsListTemplate.get(i);
			if(fr.getId().equals(id)){
				result = true;
				break;
			}
		}
		if(result){
			friendsListTemplate.remove(fr);
			int pos = findPosToInsert(fr, friendsList);
			listAdapter.insert(fr, pos);
		}
		return true;
	}
	
	private void addToList(FriendShortInfo fr, List<FriendShortInfo> fl){
		int pos = findPosToInsert(fr, fl);
		fl.add(pos, fr);
	}
	
	private int findPosToInsert(FriendShortInfo newFriend, List<FriendShortInfo> fl) {
		int friendsListSize = fl.size();
		int i;
		for(i = 0; i < friendsListSize; i++){
			if(newFriend.getId().compareTo(fl.get(i).getId()) < 0){
				break;
			}
		}
		return i;
	}
	private void removeFriend(final int location) throws Exception{
		if(location >= friendsList.size()){
			throw new Exception("removeFriend: qua kich thuoc list");
		}
		
		new AlertDialog.Builder(this)
        .setTitle("Confirm message")
        .setMessage("Do you want to remove " + friendsList.get(location).getId() +"?")
        .setPositiveButton("Yes", new OnClickListener() {
			
			public void onClick(DialogInterface dialog, int which) {
				String friendsRemove = null;
				try {
				FriendShortInfo friend = FriendsList.this.friendsList.get(location);
				friendsRemove = friend.getId();
				FriendsList.this.listAdapter.remove(friend);
				FriendsList.this.listAdapter.notifyDataSetChanged();
				FriendsList.this.friendsName.remove(friend.getId());
				} catch (Exception e)
				{
					
				} finally {
					
					staticClass.socket.println("<remove>"+friendsRemove);
				}
			}
		}
        )
        .setNegativeButton("No", null)
        .show();		
	}
	private void init(List<FriendShortInfo> list){
		txtFind = (EditText) findViewById(R.id.friendsList_txtFind);
		txtFindBehide = (TextView) findViewById(R.id.friendsList_txtFindBehide);
		friendsListTemplate = new LinkedList<FriendShortInfo>();
		friendsList = list;
		friendsName = buildFriendsName();
		listAdapter = new FriendsListAdapter(this, friendsList);
		setListAdapter(listAdapter);
		//if (!listAdapter.isEmpty()) setListAdapter(listAdapter); 
		txtFind.setOnKeyListener(new View.OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if(keyCode == KeyEvent.KEYCODE_DEL){
					restoreFriendList();
					listAdapter.notifyDataSetChanged();
				}
				String name = txtFind.getText().toString().trim();
				txtFindBehide.setText("");
				if(!name.equals(""))
					for(int i = 0; i < friendsList.size(); i++){
						FriendShortInfo fr = friendsList.get(i);
						String frId = fr.getId();
						if(frId.contains(name) == false){
							hideFriend(i--);
						}
						else if(frId.startsWith(name)){
							txtFindBehide.setText(frId);
						}
						else{
							txtFindBehide.setText(null);
						}
					}
				else{
					txtFindBehide.setText(getString(R.string.friend_findBehide));
				}
				return false;
			}
		});	
		txtFind.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Log.d("Click", "bat duoc");
				if(txtFind.getText().toString().trim().equals("")){
					restoreFriendList();
					listAdapter.notifyDataSetChanged();
					txtFindBehide.setText("");
					Log.d("Click 1", "bat duoc");
				}
				else{
					Log.d("Click 2", "bat duoc");
					String name = txtFindBehide.getText().toString();
					txtFind.setText(name);
					if(!name.equals("")){
						txtFind.setText(name);
						for(int i = 0; i < friendsList.size(); i++){
							FriendShortInfo fr = friendsList.get(i);
							String frId = fr.getId();
							if(frId.contains(name) == false){
								hideFriend(i--);
							}
						}
					}
						
					else{
						restoreFriendList();
						listAdapter.notifyDataSetChanged();
					}
				}
			}
		});
	}
	
	private List<String> buildFriendsName(){
		if(friendsList == null)
			return null;
		List<String> list = new LinkedList<String>();
		int size = friendsList.size();
		for(int i = 0; i < size; i++)
			list.add(friendsList.get(i).getId());
		
		return list;
	}
	
	private List<FriendShortInfo> receive(String value) {
		LinkedList<FriendShortInfo> result = new LinkedList<FriendShortInfo>();
	
		Log.e("error",value);
		if(value !=null)
		{
			try {
				JSONObject obj = new JSONObject(value);
				JSONArray listFriends = new JSONArray(obj.get("fList").toString());
				JSONArray listWaiting = new JSONArray(obj.get("waitList").toString());
				JSONArray listIsWaiting = new JSONArray(obj.get("isWaitList").toString());
				JSONArray list24h = new JSONArray(obj.get("24hList").toString());
				JSONArray listViewInvi = new JSONArray(obj.get("viewInviList").toString());
				JSONArray listMessage = null;
				JSONObject config = new JSONObject(obj.get("config").toString());
				
				try {
					listMessage = new JSONArray(obj.get("messageList").toString());
				} catch (Exception e)
				{
					listMessage = null;
				}
				friendsListHash = new HashMap<String, FriendShortInfo>();
			
				if (listFriends!=null) 
					for (int i = 0 ; i < listFriends.length() ; i++)
					{
						JSONObject object = listFriends.getJSONObject(i);
						String id = object.getString("user");
						String status = object.getString("status");
						String state = object.getString("state");
						String img = null;
						try {
							img = object.getString("img");
						} catch (Exception e){
							e.printStackTrace();
							img = null;
						}
						System.out.println(object.toString());
						FriendShortInfo fr = new FriendShortInfo(id, status, 
								state.startsWith("off")?false:true,img);
						int pos = findPosToInsert(fr, result);
						result.add(pos, fr);
						friendsListHash.put(fr.getId(), fr);
					}
				if (listWaiting!=null)
					for (int i = 0 ; i < listWaiting.length() ; i++)
					{
						JSONObject object = listWaiting.getJSONObject(i);
						String id = object.getString("user");
						String status = getString(R.string.friend_waitConfirm);
						FriendShortInfo fr = new FriendShortInfo(id, status,false,null);
						fr.setWaitingAdd(true);
						friendsListHash.put(fr.getId(), fr);
						result.add(fr);
					}
				
				if (listIsWaiting != null) 
					for (int i = 0 ; i < listIsWaiting.length() ; i++)
					{
						JSONObject object = listIsWaiting.getJSONObject(i);
						String id = object.getString("user");
						String cmt = object.getString("cmt");
						AcceptInviteDlg acceptDlg = new AcceptInviteDlg(this, id,cmt);
						acceptDlg.show();
					}
				if(list24h != null)
					for (int i = 0 ; i < list24h.length() ; i++)
					{
						JSONObject object = list24h.getJSONObject(i);
						FriendShortInfo fr = friendsListHash.get(object.getString("user"));
						if (fr != null) fr.setCanSee24h(true);
					}
				if(listViewInvi != null)
					for (int i = 0 ; i < listViewInvi.length() ; i++)
					{
						JSONObject object = listViewInvi.getJSONObject(i);
						FriendShortInfo fr = friendsListHash.get(object.getString("user"));
						if (fr != null) fr.setCanViewInvi(true);
					}
				if (listMessage != null)
                    for (int i = 0 ; i < listMessage.length() ; i++)
                    {
                            JSONObject object = listMessage.getJSONObject(i);
                            String uFrom = object.getString("sender");
                            String message = object.getString("msg");
                            StaticDialogs.okButtonDialog(FriendsList.this, 
                                            Html.fromHtml("User: <b><font color=\"#3399ff\">"
                                                            +uFrom+" </font></b>has sent you a message:<br/>"
                                                            +message.replaceAll("\n", "<br/>")+"<br/>"));
                            Log.d("message",message);
                    }
				
		
				int alertChat = config.getInt("alertChat");
				int alertPlace = config.getInt("alertPlace");
				boolean loadAround = config.getBoolean("loadAround");
				boolean loadFavorite = config.getBoolean("loadFavorite");
				boolean loadMyPlace = config.getBoolean("loadMyPlace");
				List<String> lsType = new ArrayList<String>();
				JSONArray jArray = new JSONArray(config.getString("listType"));
				for (int i = 0 ; i < jArray.length() ; i++)
				{
					JSONObject jObject = jArray.getJSONObject(i);
					lsType.add(jObject.getString("type"));
				}
				UserConfig uConfig = new UserConfig(alertChat, alertPlace, alertPlace, lsType, loadAround, loadFavorite, loadMyPlace);
				Bundle data = new Bundle();
				data.putSerializable("config", uConfig);
				msg = new Message();
				msg.what = UpdateLocationService.CONFIG;
				msg.setData(data);
				if (staticClass.sendToService != null) 
				{
						staticClass.sendToService.sendMessage(msg);
						msg = null;
				}
			} catch (Exception e)
			{
				e.printStackTrace();
				Log.d("error for receive",value);
			}
		}
		return result;
	}
	private void startChat(Intent intent) {
		LinkedHashMap<String, StoreMessage> listChat = service.getListChat();
		Iterator<Entry<String, StoreMessage>> iter = listChat.entrySet().iterator();
		intent.putExtra("size", listChat.size());
		int j = 0;
		while (iter.hasNext()) {
			LinkedHashMap.Entry<String, StoreMessage> entry = (LinkedHashMap.Entry) iter.next();
			intent.putExtra("user"+j, entry.getValue());
			j++;
		}
		startActivity(intent);
	}
}

